package com.gm.file_uploader.service.Impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.ObjectMetadata;
import com.gm.file_uploader.entity.Oss;
import com.gm.file_uploader.service.AliOssService;
import org.joda.time.DateTime;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.util.Date;

/**
 * 在创建这个类的时候，就应该吧属性值装载好
 */
@Service
public class AliOssServiceImpl implements AliOssService, InitializingBean {
    @Autowired
    private Oss ossEntity;

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

    /**
     * 初始化bean之后需要进行的操作
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        endpoint=ossEntity.getEndpoint();
        accessKeyId=ossEntity.getAccessKeyId();
        accessKeySecret=ossEntity.getAccessKeySecret();
        bucketName=ossEntity.getBucketName();
    }
    @Override
    public void createBucket() {
        OSS ossClient=new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
        //判断bucketName是否存在
        ossClient.createBucket(bucketName);
        ossClient.shutdown();
    }

    @Override
    public String upload(MultipartFile file){
        OSS ossClient=new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
        String uploadURL = null;
        try{


            if(!ossClient.doesBucketExist(bucketName)){
                //如果不存在，就创建bucket
                ossClient.createBucket(bucketName);
                //设置bucket的属性
                ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
            }
            //获取文件的上传流
            InputStream inputStream=file.getInputStream();
            //每次上传得到的名字不能是相同的
            String dataPath=new DateTime().toString("yyyy/mm/dd");
            String origin=file.getOriginalFilename();
            String fileName=Md5Result(file.getName());
            String fileType=origin.substring(origin.lastIndexOf("."));
            String newName=fileName+fileType;
            //生成文件夹
            fileName=dataPath+"/"+newName;

            ObjectMetadata objectMetadata=new ObjectMetadata();
            objectMetadata.setObjectAcl(CannedAccessControlList.PublicRead);
            objectMetadata.setContentType(getContentType(fileType));
            ossClient.putObject(bucketName,fileName,inputStream,objectMetadata);
            ossClient.shutdown();
            Date expiration=new Date(System.currentTimeMillis()+3600L*1000*24*365*10);
            uploadURL=ossClient.generatePresignedUrl(bucketName,fileName,expiration).toString();
        }catch(Exception e){
            e.printStackTrace();
        }
        return uploadURL.substring(0,uploadURL.indexOf("?"));
    }


    public static String Md5Result(String str) {
        StringBuffer sb = new StringBuffer();
        try {
            MessageDigest instance = MessageDigest.getInstance("MD5");
            byte[] digest = instance.digest(str.getBytes());// 对字符串加密返回字符串数组
            for (byte b : digest) {
                int i = b & 0xff;// 获取字节的低八位
                String hexString = Integer.toHexString(i);// 转换成16进制
                // 一位的话 补0
                if (hexString.length() < 2) {
                    hexString = "0" + hexString;
                }
                sb.append(hexString);
            }
            return sb.toString();

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();// 没有此算法的异常
        }
        return null;
    }
        @Override
    public void download(String fileName) throws IOException {

    }

    @Override
    public void listFile() {

    }

    @Override
    public void deleteFile(String fileName) {

    }

    /**
     * 判断oss服务上传文件时的contentType
     */
    public static String getContentType(String FilenameExtension){
        if(FilenameExtension.equalsIgnoreCase(".bmp")){
            return "image/bmp";
        }
        if(FilenameExtension.equalsIgnoreCase(".git")){
            return "image/gif";
        }
        if(FilenameExtension.equalsIgnoreCase(".jpg")
            ||FilenameExtension.equalsIgnoreCase(".jpeg")
                ||FilenameExtension.equalsIgnoreCase(".png")
        ){
            return "image/jpg";
        }
        if(FilenameExtension.equalsIgnoreCase(".html")){
            return "text/html";
        }
        else{
            return "text/txt";
        }
    }
}
